<?php

class Light_View
{
	/**
	 * Script name
	 *
	 * @var string
	 */
	protected $_viewScriptName = null;

    /**
     * @var Light_Controller
     */
    protected $_controller;

    /**
     * @var array
     */
    protected $_pathScripts = array();

    /**
     * @var array
     */
    protected $_pathHelpers = array();

    /**
     * @var array of Light_View_Helper_Abstract
     */
    public static $helpers = array();

    /**
     * @param Light_Controller $controller
     */
    public function __construct(Light_Controller $controller = null)
    {
        $this->_controller = $controller;

        if ($this->getViewScriptName() === null) {
            $this->setViewScriptName($controller->getActionName());
        }

        if (Light_Core::$isAdmin) {
            $this->addPathScript(LIGHT_APPLICATION_PATH . '/modules/' . $controller->getModuleName() . '/views/scripts/admin/' . $controller->getControllerName());
            $this->addPathScript(LIGHT_APPLICATION_PATH . '/modules/default/views/scripts/admin/' . $controller->getControllerName());
            $this->addPathScript(LIGHT_APPLICATION_PATH . '/modules/default/views/scripts/admin');
        } else {
            $this->addPathScript(LIGHT_APPLICATION_PATH . '/modules/' . $controller->getModuleName() . '/views/scripts/' . $controller->getControllerName());
            $this->addPathScript(LIGHT_APPLICATION_PATH . '/modules/default/views/scripts/' . $controller->getControllerName());
            $this->addPathScript(LIGHT_APPLICATION_PATH . '/modules/default/views/scripts');
        }

        $this->addPathHelpers(LIGHT_APPLICATION_PATH .'/modules/default/views/helpers/scripts');
    }

    /**
     * @return the $_viewScriptName
     */
    public function getViewScriptName ()
    {
    	return $this->_viewScriptName;
    }

    /**
     * Set view script name object
     *
     * @param string $viewScriptName
     * @return Core oject
     */
    public function setViewScriptName($viewScriptName)
    {
    	$this->_viewScriptName = $viewScriptName;

    	return $this;
    }

    /**
     * @param string $path
     * @return Light_View
     */
    public function addPathScript($path)
    {
        $this->_pathScripts[sha1($path)] = $path;

        return $this;
    }

    /**
     * @param string $path
     * @return Light_View
     */
    public function addPathHelpers($path)
    {
        $this->_pathHelpers[sha1($path)] = $path;

        return $this;
    }

    /**
     * @param string $viewScriptName
     * @param boolean $isHelper
     * @throws Light_Exception
     * @return string
     */
    public function render($viewScriptName = null, $isHelper = false)
    {
        $lookedView = $viewScriptName !== null ? $viewScriptName : $this->getViewScriptName();

        $holder = $isHelper ? $this->_pathHelpers : $this->_pathScripts;

        foreach ($holder as $path) {
            $file = $path . '/' . $lookedView . '.phtml';
            if (!is_readable($file)) {
                continue;
            }
            if (isset($this->errors) && !empty($this->errors)) {
                foreach ($this->errors as $key => $value) {
                    $this->errors[$key] = $this->translate($value);
                }
            }
            ob_start();
            require $file;
            return ob_get_clean();
        }

        throw new Light_Exception('View "' . $lookedView . '" not found in : ' . implode(', ', $this->_pathScripts), 404);
    }

    /**
     * @param string | array $key
     * @param mixed $value
     */
    public function assign($key, $value)
    {
        if (is_array($key)) {
            foreach ($key as $k => $v) {
                $this->{$k} = $v;
            }
        } else {
            $this->{$key} = $value;
        }
    }

    /**
     * @return Light_Controller
     */
    public function getController()
    {
        return $this->_controller;
    }

    /**
     * @param string $name
     * @param array $args
     * @return mixed
     */
    public function __call($name, $args)
    {
        $helper = $this->getHelper($name);

        if (!method_exists($helper, $name)) {
            throw new Light_Exception("Method '{$name}' does not exists in helper '" . get_class($helper) . "'");
        }

        $argc = count($args);

        switch ($argc) {
            case 0 :
                $helper = $helper->$name();
                break;
            case 1 :
                $helper = $helper->$name($args[0]);
                break;
            case 2 :
                $helper = $helper->$name($args[0], $args[1]);
                break;
            case 3 :
                $helper = $helper->$name($args[0], $args[1], $args[2]);
                break;
            case 4 :
                $helper = $helper->$name($args[0], $args[1], $args[2], $args[3]);
                break;
            default:
                $helper = call_user_func_array(array($helper, $name), $args);
        }

        return $helper;
    }

    /**
     * @param string $name
     * @throws Light_Exception
     * @return Light_View_Helper_Abstract
     */
    public function getHelper($name)
    {
        if (isset(self::$helpers[$name])) {
            return self::$helpers[$name];
        }

        $class = 'Light_View_Helper_' . ucfirst($name);

        if (Light_Loader::loadClass($class)) {
            self::$helpers[$name] = new $class();
        } else {
            $helpers = glob(LIGHT_APPLICATION_PATH . '/' . 'modules/*/views/helpers/*.php');
            if (is_array($helpers) && !empty($helpers)) {
                foreach ($helpers as $helper) {
                    $helper = explode('/', $helper);
                    $module = $helper[count($helper) - 4];
                    $helper = $helper[count($helper) - 1];
                    $helper = substr($helper, 0, -4);
                    if (strtolower($helper) === strtolower($name)) {
                        $class = ucfirst($module) . '_View_Helper_' . ucfirst($name);
                        if (Light_Loader::loadClass($class)) {
                            self::$helpers[$name] = new $class();
                            $this->addPathHelpers(LIGHT_APPLICATION_PATH . '/modules/' . $module . '/views/helpers/scripts');
                        }
                        break;
                    }
                }
            }
        }

        if (!isset(self::$helpers[$name])) {
        	throw new Light_Exception('Invalid helper: ' . $name);
        }

        self::$helpers[$name]->setView($this);

        return self::$helpers[$name];
    }
}